package org.egrit;

import java.awt.Point;


/**
 * A grid whose values are calculated by a {@linkplain GridFunction}.
 * <p>
 * Note: the methods {@linkplain #lock()} and {@linkplain #unlock()} do nothing
 * in this class.
 * 
 * @author michael
 */
public class CalculatedGrid extends AbstractGrid {
    private final GridFunction valueFn;

    /**
     * Creates a new calculated grid.
     * 
     * @param width grid width
     * @param height grid height
     * @param valueFn function for grid values
     * @param outsideValue value to return for requests outside the bounds of this grid
     */
    public CalculatedGrid(int width, int height, GridFunction valueFn, Number outsideValue) {
        this(GridBoundsFactory.create(0, width - 1, 0, height - 1), valueFn, outsideValue);
    }
    
    /**
     * Creates a new calculated grid.
     * 
     * @param bounds grid bounds
     * @param valueFn function for grid values
     * @param outsideValue value to return for requests outside the bounds of this grid
     */
    public CalculatedGrid(IGridBounds bounds, GridFunction valueFn, Number outsideValue) {
        super(bounds, outsideValue);
        this.valueFn = valueFn;
    }

    @Override
    public Number getGridValue(int gridX, int gridY) {
        if (isWithin(gridX, gridY)) {
            return valueFn.apply(this, gridX, gridY);
        }
        return outsideValue;
    }

    @Override
    public Number getGridValue(Point gridPos) {
        return getGridValue(gridPos.x, gridPos.y);
    }

}
